package ui;

import java.awt.List;

/**
 * Combines model and view for a list. The model is an array of Objects, the
 * view presents their string representations and lets the user select multiple
 * items from the list.
 * 
 * @version 1.0
 * @author Hans U. Gerber (<a
 *         href="mailto:gerber@ifh.ee.ethz.ch">gerber@ifh.ee.ethz.ch</a>)
 */
public class SetUI extends List implements Validatable {
	private String label;
	private Object[] choices;
	private int[] selections;

	/**
	 * @param label
	 *            a descriptive label for the list component
	 * @param choices
	 *            an array of Objects to select from
	 * @param selections
	 *            the indices of the initially selected items
	 */
	public SetUI(String label, Object[] choices, int[] selections) {
		super(0, true);
		this.label = label;
		this.choices = choices;
		this.selections = selections;
		if (choices != null) {
			for (int i = 0; i < choices.length; i++) {
				addItem(choices[i].toString());
			}
		}
		display();
	}

	public void display() {
		for (int i = 0; i < countItems(); i++) {
			deselect(i);
		}
		if (selections != null) {
			for (int i = 0; i < selections.length; i++) {
				select(selections[i]);
			}
		}
	}

	/**
	 * Checks if the users selections are valid. In my application, the user
	 * must select at least one item.
	 * 
	 * @return <code>null</code> if the selection is valid, an error message
	 *         otherwise
	 */
	public String check() {
		if (getSelectedIndexes().length > 0) {
			return null;
		} else {
			return "In \"" + label + "\", at least one item must be selected.";
		}
	}

	/**
	 * @return the number of selected items
	 */
	public int countSelections() {
		if (selections == null) {
			return 0;
		} else {
			return selections.length;
		}
	}

	/**
	 * @return the object corresponding to a list index
	 */
	public Object getSelectedItem(int selectionNr) {
		if (choices == null || selections == null) {
			return null;
		} else {
			return choices[selections[selectionNr]];
		}
	}

	public String getLabel() {
		return label;
	}

	/**
	 * Transfers the user's selections -- the indices of the selected items --
	 * from the visible component to the internal model.
	 */
	public void accept() {
		selections = getSelectedIndexes();
	}
}
